;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; solution 1
;;; 9999999 is an easy upper limit to come up with. 7 times 9! is less than 9999999.
;;; but takes too much time once set upper limit to 9999999
;;; could improve like: skip compare if the factorial of larget digit is larger than itself
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
(defun digits (num)
  (map 'list
       (lambda (char) (read-from-string (string char)))
       (prin1-to-string num)))

(defun factorial (n)
  (if (<= n 1) 1
      (* n (factorial (1- n)))))

(defun sum-of-factorial-digits (n)
  (reduce
   '+
   (mapcar
     (lambda (x) (factorial x))
     (digits n))))

(defun max-factorial-digits (n)
  (factorial
    (apply 'max (digits n))))

(defun p34 ()
  (loop for i from 3 to 99999
    when (and (> i (max-factorial-digits i)) (= i (sum-of-factorial-digits i)))
    collect i))

(format t "~a~%" (p34))
;(format t "~a~%" (reduce '+ (p34)))
;(format t "~a~%" (max-factorial-digits 125))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; use following method and set upper limit to 9999999 would be better
(defun digit-fact (n)
  (aref #(1 1 2 6 24 120 720 5040 40320 362880 3628800) n))
 
(defun fact-sum (num)
  (apply #'+ (mapcar #'digit-fact (digits num))))
 
